From 9f1d6e1f4474707aa9931660da6c3154b2281705 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 7 Jul 2021 04:40:34 +0200 Subject: [PATCH] gl: Move vfunc Instead of Display::make_gl_context_current() we now have GLContext::clear_current() GLContext::make_current() This fits better with the backends (we can actually implement clearCurrent on macOS now) and makes it easier to implement different GL backends for backends (like EGL/GLX on X11). We also pass a surfaceless boolean to make_current() so the calling code can decide if a surface needs to be bound or not, because the backends were all doing whatever, which was very counterproductive. --- gdk/gdkdisplay.c | 15 --- gdk/gdkdisplayprivate.h | 4 - gdk/gdkglcontext.c | 25 ++-- gdk/gdkglcontextprivate.h | 3 + gdk/macos/gdkmacosdisplay.c | 14 -- gdk/macos/gdkmacosglcontext-private.h | 1 - gdk/macos/gdkmacosglcontext.c | 78 +++++++---- gdk/wayland/gdkdisplay-wayland.c | 1 - gdk/wayland/gdkglcontext-wayland.c | 66 +++++----- gdk/wayland/gdkglcontext-wayland.h | 2 - gdk/win32/gdkdisplay-win32.c | 1 - gdk/win32/gdkglcontext-win32.c | 183 +++++++++++++------------- gdk/win32/gdkglcontext-win32.h | 3 - gdk/x11/gdkdisplay-x11.c | 1 - gdk/x11/gdkglcontext-egl.c | 131 +++++++++--------- gdk/x11/gdkglcontext-glx.c | 123 ++++++++--------- gdk/x11/gdkglcontext-x11.c | 16 --- gdk/x11/gdkglcontext-x11.h | 6 - 18 files changed, 319 insertions(+), 354 deletions(-) diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c index 5891bbe5f0..8da1a4cc9f 100644 --- a/gdk/gdkdisplay.c +++ b/gdk/gdkdisplay.c @@ -1298,21 +1298,6 @@ gdk_display_get_gl_context (GdkDisplay *self) return priv->gl_context; } -/*< private > - * gdk_display_make_gl_context_current: - * @display: a `GdkDisplay` - * @context: (optional): a `GdkGLContext` - * - * Makes the given @context the current GL context, or unsets - * the current GL context if @context is %NULL. - */ -gboolean -gdk_display_make_gl_context_current (GdkDisplay *display, - GdkGLContext *context) -{ - return GDK_DISPLAY_GET_CLASS (display)->make_gl_context_current (display, context); -} - GdkDebugFlags gdk_display_get_debug_flags (GdkDisplay *display) { diff --git a/gdk/gdkdisplayprivate.h b/gdk/gdkdisplayprivate.h index a2913b50e9..a85b275db7 100644 --- a/gdk/gdkdisplayprivate.h +++ b/gdk/gdkdisplayprivate.h @@ -142,8 +142,6 @@ struct _GdkDisplayClass GdkGLContext * (*init_gl) (GdkDisplay *display, GError **error); - gboolean (*make_gl_context_current) (GdkDisplay *display, - GdkGLContext *context); GdkSeat * (*get_default_seat) (GdkDisplay *display); @@ -209,8 +207,6 @@ GdkSurface * gdk_display_create_surface (GdkDisplay *display int height); GdkGLContext * gdk_display_get_gl_context (GdkDisplay *display); -gboolean gdk_display_make_gl_context_current (GdkDisplay *display, - GdkGLContext *context); void gdk_display_set_rgba (GdkDisplay *display, gboolean rgba); diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c index c962ae903f..06a9de118e 100644 --- a/gdk/gdkglcontext.c +++ b/gdk/gdkglcontext.c @@ -128,9 +128,10 @@ G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkGLContext, gdk_gl_context, GDK_TYPE_DRAW typedef struct _MaskedContext MaskedContext; static inline MaskedContext * -mask_context (GdkGLContext *context) +mask_context (GdkGLContext *context, + gboolean surfaceless) { - return (MaskedContext *) GSIZE_TO_POINTER (GPOINTER_TO_SIZE (context) | (gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context)) ? 1 : 0)); + return (MaskedContext *) GSIZE_TO_POINTER (GPOINTER_TO_SIZE (context) | (surfaceless ? 1 : 0)); } static inline GdkGLContext * @@ -1138,10 +1139,12 @@ gdk_gl_context_make_current (GdkGLContext *context) { GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context); MaskedContext *current, *masked_context; + gboolean surfaceless; g_return_if_fail (GDK_IS_GL_CONTEXT (context)); - masked_context = mask_context (context); + surfaceless = !gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context)); + masked_context = mask_context (context, surfaceless); current = g_private_get (&thread_current_context); if (current == masked_context) @@ -1161,12 +1164,15 @@ gdk_gl_context_make_current (GdkGLContext *context) } } - if (gdk_display_make_gl_context_current (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)), context)) + if (!GDK_GL_CONTEXT_GET_CLASS (context)->make_current (context, surfaceless)) { - g_object_ref (context); - g_private_replace (&thread_current_context, masked_context); - gdk_gl_context_check_extensions (context); + g_warning ("gdk_gl_context_make_current() failed"); + return; } + + g_object_ref (context); + g_private_replace (&thread_current_context, masked_context); + gdk_gl_context_check_extensions (context); } /** @@ -1265,8 +1271,9 @@ gdk_gl_context_clear_current (void) current = g_private_get (&thread_current_context); if (current != NULL) { - GdkGLContext *current_context = unmask_context (current); - if (gdk_display_make_gl_context_current (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (current_context)), NULL)) + GdkGLContext *context = unmask_context (current); + + if (GDK_GL_CONTEXT_GET_CLASS (context)->clear_current (context)) g_private_replace (&thread_current_context, NULL); } } diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h index b64a6f4510..a338d7cbbe 100644 --- a/gdk/gdkglcontextprivate.h +++ b/gdk/gdkglcontextprivate.h @@ -55,6 +55,9 @@ struct _GdkGLContextClass gboolean (* realize) (GdkGLContext *context, GError **error); + gboolean (* make_current) (GdkGLContext *context, + gboolean surfaceless); + gboolean (* clear_current) (GdkGLContext *context); cairo_region_t * (* get_damage) (GdkGLContext *context); gboolean (* is_shared) (GdkGLContext *self, diff --git a/gdk/macos/gdkmacosdisplay.c b/gdk/macos/gdkmacosdisplay.c index 351ff574fd..93afcce196 100644 --- a/gdk/macos/gdkmacosdisplay.c +++ b/gdk/macos/gdkmacosdisplay.c @@ -644,19 +644,6 @@ gdk_macos_display_init_gl (GdkDisplay *display, return _gdk_macos_gl_context_new (display, NULL, FALSE, NULL, error); } -static gboolean -gdk_macos_display_make_gl_context_current (GdkDisplay *display, - GdkGLContext *gl_context) -{ - g_assert (GDK_IS_MACOS_DISPLAY (display)); - g_assert (!gl_context || GDK_IS_MACOS_GL_CONTEXT (gl_context)); - - if (gl_context == NULL) - return FALSE; - - return _gdk_macos_gl_context_make_current (GDK_MACOS_GL_CONTEXT (gl_context)); -} - static void gdk_macos_display_finalize (GObject *object) { @@ -703,7 +690,6 @@ gdk_macos_display_class_init (GdkMacosDisplayClass *klass) display_class->get_setting = gdk_macos_display_get_setting; display_class->has_pending = gdk_macos_display_has_pending; display_class->init_gl = gdk_macos_display_init_gl; - display_class->make_gl_context_current = gdk_macos_display_make_gl_context_current; display_class->notify_startup_complete = gdk_macos_display_notify_startup_complete; display_class->queue_events = gdk_macos_display_queue_events; display_class->sync = gdk_macos_display_sync; diff --git a/gdk/macos/gdkmacosglcontext-private.h b/gdk/macos/gdkmacosglcontext-private.h index 8d5eea931c..a09a2da905 100644 --- a/gdk/macos/gdkmacosglcontext-private.h +++ b/gdk/macos/gdkmacosglcontext-private.h @@ -62,7 +62,6 @@ GdkGLContext *_gdk_macos_gl_context_new (GdkMacosDisplay *display, gboolean attached, GdkGLContext *share, GError **error); -gboolean _gdk_macos_gl_context_make_current (GdkMacosGLContext *self); G_END_DECLS diff --git a/gdk/macos/gdkmacosglcontext.c b/gdk/macos/gdkmacosglcontext.c index 58d688e890..9b23fe929a 100644 --- a/gdk/macos/gdkmacosglcontext.c +++ b/gdk/macos/gdkmacosglcontext.c @@ -403,6 +403,57 @@ gdk_macos_gl_context_surface_resized (GdkDrawContext *draw_context) g_clear_pointer (&self->damage, cairo_region_destroy); } +static gboolean +gdk_macos_gl_context_clear_current (GdkGLContext *context) +{ + GdkMacosGLContext *self = GDK_MACOS_GL_CONTEXT (context); + NSOpenGLContext *current; + + g_return_val_if_fail (GDK_IS_MACOS_GL_CONTEXT (self), FALSE); + + current = [NSOpenGLContext currentContext]; + + if (self->gl_context == current) + { + /* The OpenGL mac programming guide suggests that glFlush() is called + * before switching current contexts to ensure that the drawing commands + * are submitted. + */ + if (current != NULL) + glFlush (); + + [NSOpenGLContext clearCurrentContext]; + } + + return TRUE; +} + +static gboolean +gdk_macos_gl_context_make_current (GdkGLContext *context, + gboolean surfaceless) +{ + GdkMacosGLContext *self = GDK_MACOS_GL_CONTEXT (context); + NSOpenGLContext *current; + + g_return_val_if_fail (GDK_IS_MACOS_GL_CONTEXT (self), FALSE); + + current = [NSOpenGLContext currentContext]; + + if (self->gl_context != current) + { + /* The OpenGL mac programming guide suggests that glFlush() is called + * before switching current contexts to ensure that the drawing commands + * are submitted. + */ + if (current != NULL) + glFlush (); + + [self->gl_context makeCurrentContext]; + } + + return TRUE; +} + static cairo_region_t * gdk_macos_gl_context_get_damage (GdkGLContext *context) { @@ -494,31 +545,4 @@ _gdk_macos_gl_context_new (GdkMacosDisplay *display, return GDK_GL_CONTEXT (context); } -gboolean -_gdk_macos_gl_context_make_current (GdkMacosGLContext *self) -{ - NSOpenGLContext *current; - - g_return_val_if_fail (GDK_IS_MACOS_GL_CONTEXT (self), FALSE); - - if (self->gl_context == NULL) - return FALSE; - - current = [NSOpenGLContext currentContext]; - - if (self->gl_context != current) - { - /* The OpenGL mac programming guide suggests that glFlush() is called - * before switching current contexts to ensure that the drawing commands - * are submitted. - */ - if (current != NULL) - glFlush (); - - [self->gl_context makeCurrentContext]; - } - - return TRUE; -} - G_GNUC_END_IGNORE_DEPRECATIONS diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 5d2d3826ae..0312411e0c 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -970,7 +970,6 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass *class) display_class->get_keymap = _gdk_wayland_display_get_keymap; display_class->init_gl = gdk_wayland_display_init_gl; - display_class->make_gl_context_current = gdk_wayland_display_make_gl_context_current; display_class->get_monitors = gdk_wayland_display_get_monitors; display_class->get_monitor_at_surface = gdk_wayland_display_get_monitor_at_surface; diff --git a/gdk/wayland/gdkglcontext-wayland.c b/gdk/wayland/gdkglcontext-wayland.c index de60ebc820..2a2e03300d 100644 --- a/gdk/wayland/gdkglcontext-wayland.c +++ b/gdk/wayland/gdkglcontext-wayland.c @@ -245,6 +245,37 @@ gdk_wayland_gl_context_get_damage (GdkGLContext *context) return GDK_GL_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->get_damage (context); } +static gboolean +gdk_wayland_gl_context_clear_current (GdkGLContext *context) +{ + GdkDisplay *display = gdk_gl_context_get_display (context); + GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display); + + return eglMakeCurrent (display_wayland->egl_display, + EGL_NO_SURFACE, + EGL_NO_SURFACE, + EGL_NO_CONTEXT); +} + +static gboolean +gdk_wayland_gl_context_make_current (GdkGLContext *context, + gboolean surfaceless) +{ + GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (context); + GdkDisplay *display = gdk_gl_context_get_display (context); + GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display); + EGLSurface egl_surface; + + if (!surfaceless) + egl_surface = gdk_wayland_surface_get_egl_surface (gdk_gl_context_get_surface (context)); + else + egl_surface = EGL_NO_SURFACE; + + return eglMakeCurrent (display_wayland->egl_display, + egl_surface, + egl_surface, + context_wayland->egl_context); +} static void gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context, cairo_region_t *painted) @@ -309,6 +340,8 @@ gdk_wayland_gl_context_class_init (GdkWaylandGLContextClass *klass) draw_context_class->end_frame = gdk_wayland_gl_context_end_frame; context_class->realize = gdk_wayland_gl_context_realize; + context_class->make_current = gdk_wayland_gl_context_make_current; + context_class->clear_current = gdk_wayland_gl_context_clear_current; context_class->get_damage = gdk_wayland_gl_context_get_damage; } @@ -556,36 +589,3 @@ gdk_wayland_gl_context_dispose (GObject *gobject) G_OBJECT_CLASS (gdk_wayland_gl_context_parent_class)->dispose (gobject); } -gboolean -gdk_wayland_display_make_gl_context_current (GdkDisplay *display, - GdkGLContext *context) -{ - GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display); - GdkWaylandGLContext *context_wayland; - GdkSurface *surface; - EGLSurface egl_surface; - - if (context == NULL) - { - eglMakeCurrent(display_wayland->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, - EGL_NO_CONTEXT); - return TRUE; - } - - context_wayland = GDK_WAYLAND_GL_CONTEXT (context); - surface = gdk_gl_context_get_surface (context); - - if (gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context))) - egl_surface = gdk_wayland_surface_get_egl_surface (surface); - else - egl_surface = EGL_NO_SURFACE; - - if (!eglMakeCurrent (display_wayland->egl_display, egl_surface, - egl_surface, context_wayland->egl_context)) - { - g_warning ("eglMakeCurrent failed"); - return FALSE; - } - - return TRUE; -} diff --git a/gdk/wayland/gdkglcontext-wayland.h b/gdk/wayland/gdkglcontext-wayland.h index 98a2a7b62e..add5807849 100644 --- a/gdk/wayland/gdkglcontext-wayland.h +++ b/gdk/wayland/gdkglcontext-wayland.h @@ -47,8 +47,6 @@ GdkGLContext * gdk_wayland_display_init_gl (GdkDisplay GError **error); GdkGLContext * gdk_wayland_surface_create_gl_context (GdkSurface *surface, GError **error); -gboolean gdk_wayland_display_make_gl_context_current (GdkDisplay *display, - GdkGLContext *context); G_END_DECLS diff --git a/gdk/win32/gdkdisplay-win32.c b/gdk/win32/gdkdisplay-win32.c index 42577b2c2f..fe2a4ff480 100644 --- a/gdk/win32/gdkdisplay-win32.c +++ b/gdk/win32/gdkdisplay-win32.c @@ -1165,7 +1165,6 @@ gdk_win32_display_class_init (GdkWin32DisplayClass *klass) display_class->create_surface = _gdk_win32_display_create_surface; display_class->get_keymap = _gdk_win32_display_get_keymap; - display_class->make_gl_context_current = _gdk_win32_display_make_gl_context_current; display_class->get_monitors = gdk_win32_display_get_monitors; diff --git a/gdk/win32/gdkglcontext-win32.c b/gdk/win32/gdkglcontext-win32.c index 68e021d2d7..9d87b89e0a 100644 --- a/gdk/win32/gdkglcontext-win32.c +++ b/gdk/win32/gdkglcontext-win32.c @@ -1046,113 +1046,40 @@ gdk_win32_gl_context_realize (GdkGLContext *context, return TRUE; } -static void -gdk_win32_gl_context_class_init (GdkWin32GLContextClass *klass) -{ - GdkGLContextClass *gl_context_class = GDK_GL_CONTEXT_CLASS(klass); - GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS(klass); - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gl_context_class->realize = gdk_win32_gl_context_realize; - - draw_context_class->begin_frame = gdk_win32_gl_context_begin_frame; - draw_context_class->end_frame = gdk_win32_gl_context_end_frame; - - gobject_class->dispose = _gdk_win32_gl_context_dispose; -} - -static void -gdk_win32_gl_context_init (GdkWin32GLContext *self) -{ -} - -GdkGLContext * -_gdk_win32_surface_create_gl_context (GdkSurface *surface, - GError **error) +static gboolean +gdk_win32_gl_context_clear_current (GdkGLContext *context) { - GdkDisplay *display = gdk_surface_get_display (surface); + GdkDisplay *display = gdk_gl_context_get_display (context); GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display); - GdkWin32GLContext *context = NULL; - GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface); #ifdef GDK_WIN32_ENABLE_EGL - EGLContext egl_context; - EGLConfig config; -#endif - - impl->hdc = GetDC (GDK_SURFACE_HWND (surface)); - -#ifdef GDK_WIN32_ENABLE_EGL - /* display_win32->hdc_egl_temp should *not* be destroyed here! It is destroyed at dispose()! */ - display_win32->hdc_egl_temp = impl->hdc; -#endif - - if (!_gdk_win32_display_init_gl (display)) - { - g_set_error_literal (error, GDK_GL_ERROR, - GDK_GL_ERROR_NOT_AVAILABLE, - _("No GL implementation is available")); - return NULL; - } - -#ifdef GDK_WIN32_ENABLE_EGL - if (display_win32->have_egl && !find_eglconfig_for_window (display_win32, &config, - &display_win32->egl_min_swap_interval, error)) - return NULL; -#endif - - context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT, - "surface", surface, - NULL); - - context->gl_hdc = impl->hdc; - -#ifdef GDK_WIN32_ENABLE_EGL - if (display_win32->have_egl) - context->egl_config = config; + if (display_win32->egl_disp != EGL_NO_DISPLAY) + return eglMakeCurrent (display_win32->egl_disp, + EGL_NO_SURFACE, + EGL_NO_SURFACE, + EGL_NO_CONTEXT); + else #endif - - return GDK_GL_CONTEXT (context); + return wglMakeCurrent (NULL, NULL); } -gboolean -_gdk_win32_display_make_gl_context_current (GdkDisplay *display, - GdkGLContext *context) +static gboolean +gdk_win32_gl_context_make_current (GdkGLContext *context, + gboolean surfaceless) { - GdkWin32GLContext *context_win32; + GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context); + GdkDisplay *display = gdk_gl_context_get_display (context); GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display); GdkSurface *surface; gboolean do_frame_sync = FALSE; - if (context == NULL) - { -#ifdef GDK_WIN32_ENABLE_EGL - if (display_win32->egl_disp != EGL_NO_DISPLAY) - eglMakeCurrent(display_win32->egl_disp, - EGL_NO_SURFACE, - EGL_NO_SURFACE, - EGL_NO_CONTEXT); - else -#endif - wglMakeCurrent(NULL, NULL); - - return TRUE; - } - - context_win32 = GDK_WIN32_GL_CONTEXT (context); - if (!gdk_gl_context_get_use_es (context)) { if (!wglMakeCurrent (context_win32->gl_hdc, context_win32->hglrc)) - { - GDK_NOTE (OPENGL, - g_print ("Making WGL context current failed\n")); - return FALSE; - } + return FALSE; - if (gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context)) && - display_win32->hasWglEXTSwapControl) + if (!surfaceless && display_win32->hasWglEXTSwapControl) { surface = gdk_gl_context_get_surface (context); @@ -1182,7 +1109,7 @@ _gdk_win32_display_make_gl_context_current (GdkDisplay *display, surface = gdk_gl_context_get_surface (context); - if (gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context))) + if (!surfaceless) egl_surface = _gdk_win32_surface_get_egl_surface (surface, context_win32->egl_config, FALSE); else { @@ -1196,10 +1123,7 @@ _gdk_win32_display_make_gl_context_current (GdkDisplay *display, egl_surface, egl_surface, context_win32->egl_context)) - { - g_warning ("eglMakeCurrent failed"); - return FALSE; - } + return FALSE; if (display_win32->egl_min_swap_interval == 0) eglSwapInterval (display_win32->egl_disp, 0); @@ -1211,6 +1135,75 @@ _gdk_win32_display_make_gl_context_current (GdkDisplay *display, return TRUE; } +static void +gdk_win32_gl_context_class_init (GdkWin32GLContextClass *klass) +{ + GdkGLContextClass *gl_context_class = GDK_GL_CONTEXT_CLASS(klass); + GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS(klass); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gl_context_class->realize = gdk_win32_gl_context_realize; + + draw_context_class->begin_frame = gdk_win32_gl_context_begin_frame; + draw_context_class->end_frame = gdk_win32_gl_context_end_frame; + + gobject_class->dispose = _gdk_win32_gl_context_dispose; +} + +static void +gdk_win32_gl_context_init (GdkWin32GLContext *self) +{ +} + +GdkGLContext * +_gdk_win32_surface_create_gl_context (GdkSurface *surface, + GError **error) +{ + GdkDisplay *display = gdk_surface_get_display (surface); + GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display); + GdkWin32GLContext *context = NULL; + GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface); + +#ifdef GDK_WIN32_ENABLE_EGL + EGLContext egl_context; + EGLConfig config; +#endif + + impl->hdc = GetDC (GDK_SURFACE_HWND (surface)); + +#ifdef GDK_WIN32_ENABLE_EGL + /* display_win32->hdc_egl_temp should *not* be destroyed here! It is destroyed at dispose()! */ + display_win32->hdc_egl_temp = impl->hdc; +#endif + + if (!_gdk_win32_display_init_gl (display)) + { + g_set_error_literal (error, GDK_GL_ERROR, + GDK_GL_ERROR_NOT_AVAILABLE, + _("No GL implementation is available")); + return NULL; + } + +#ifdef GDK_WIN32_ENABLE_EGL + if (display_win32->have_egl && !find_eglconfig_for_window (display_win32, &config, + &display_win32->egl_min_swap_interval, error)) + return NULL; +#endif + + context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT, + "surface", surface, + NULL); + + context->gl_hdc = impl->hdc; + +#ifdef GDK_WIN32_ENABLE_EGL + if (display_win32->have_egl) + context->egl_config = config; +#endif + + return GDK_GL_CONTEXT (context); +} + /** * gdk_win32_display_get_wgl_version: * @display: a `GdkDisplay` diff --git a/gdk/win32/gdkglcontext-win32.h b/gdk/win32/gdkglcontext-win32.h index c000b8143b..5a66334fca 100644 --- a/gdk/win32/gdkglcontext-win32.h +++ b/gdk/win32/gdkglcontext-win32.h @@ -63,9 +63,6 @@ GdkGLContext * _gdk_win32_surface_create_gl_context (GdkSurface *window, GError **error); -gboolean -_gdk_win32_display_make_gl_context_current (GdkDisplay *display, - GdkGLContext *context); void _gdk_win32_surface_invalidate_egl_framebuffer (GdkSurface *surface); diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c index d391a608c8..6ea0833948 100644 --- a/gdk/x11/gdkdisplay-x11.c +++ b/gdk/x11/gdkdisplay-x11.c @@ -2923,7 +2923,6 @@ gdk_x11_display_class_init (GdkX11DisplayClass * class) display_class->get_keymap = gdk_x11_display_get_keymap; display_class->init_gl = gdk_x11_display_init_gl; - display_class->make_gl_context_current = gdk_x11_display_make_gl_context_current; display_class->get_default_seat = gdk_x11_display_get_default_seat; diff --git a/gdk/x11/gdkglcontext-egl.c b/gdk/x11/gdkglcontext-egl.c index 632209a43f..2248adaf2c 100644 --- a/gdk/x11/gdkglcontext-egl.c +++ b/gdk/x11/gdkglcontext-egl.c @@ -360,6 +360,70 @@ gdk_x11_gl_context_egl_end_frame (GdkDrawContext *draw_context, eglSwapBuffers (display_x11->egl_display, egl_surface); } +static gboolean +gdk_x11_gl_context_egl_clear_current (GdkGLContext *context) +{ + GdkDisplay *display = gdk_gl_context_get_display (context); + GdkX11Display *display_x11 = GDK_X11_DISPLAY (display); + + return eglMakeCurrent (display_x11->egl_display, + EGL_NO_SURFACE, + EGL_NO_SURFACE, + EGL_NO_CONTEXT); +} + +static gboolean +gdk_x11_gl_context_egl_make_current (GdkGLContext *context, + gboolean surfaceless) +{ + GdkX11GLContextEGL *context_egl = GDK_X11_GL_CONTEXT_EGL (context); + GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context); + GdkDisplay *display = gdk_gl_context_get_display (context); + GdkX11Display *display_x11 = GDK_X11_DISPLAY (display); + GdkSurface *surface; + EGLSurface egl_surface; + gboolean do_frame_sync = FALSE; + + if (surfaceless) + { + return eglMakeCurrent (display_x11->egl_display, + EGL_NO_SURFACE, + EGL_NO_SURFACE, + context_egl->egl_context); + } + + surface = gdk_gl_context_get_surface (context); + egl_surface = gdk_x11_surface_get_egl_surface (surface); + + GDK_DISPLAY_NOTE (display, OPENGL, + g_message ("Making EGL context %p current to surface %p", + context_egl->egl_context, egl_surface)); + + if (!eglMakeCurrent (display_x11->egl_display, + egl_surface, + egl_surface, + context_egl->egl_context)) + return FALSE; + + /* If the WM is compositing there is no particular need to delay + * the swap when drawing on the offscreen, rendering to the screen + * happens later anyway, and its up to the compositor to sync that + * to the vblank. */ + do_frame_sync = ! gdk_display_is_composited (display); + + if (do_frame_sync != context_x11->do_frame_sync) + { + context_x11->do_frame_sync = do_frame_sync; + + if (do_frame_sync) + eglSwapInterval (display_x11->egl_display, 1); + else + eglSwapInterval (display_x11->egl_display, 0); + } + + return TRUE; +} + static cairo_region_t * gdk_x11_gl_context_egl_get_damage (GdkGLContext *context) { @@ -569,6 +633,8 @@ gdk_x11_gl_context_egl_class_init (GdkX11GLContextEGLClass *klass) GObjectClass *gobject_class = G_OBJECT_CLASS (klass); context_class->realize = gdk_x11_gl_context_egl_realize; + context_class->make_current = gdk_x11_gl_context_egl_make_current; + context_class->clear_current = gdk_x11_gl_context_egl_clear_current; context_class->get_damage = gdk_x11_gl_context_egl_get_damage; draw_context_class->end_frame = gdk_x11_gl_context_egl_end_frame; @@ -689,71 +755,6 @@ gdk_x11_gl_context_egl_new (GdkSurface *surface, return GDK_X11_GL_CONTEXT (context); } -gboolean -gdk_x11_gl_context_egl_make_current (GdkDisplay *display, - GdkGLContext *context) -{ - GdkX11GLContextEGL *context_egl = GDK_X11_GL_CONTEXT_EGL (context); - GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context); - GdkX11Display *display_x11 = GDK_X11_DISPLAY (display); - GdkSurface *surface; - EGLSurface egl_surface; - - if (context == NULL) - { - eglMakeCurrent (display_x11->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - return TRUE; - } - - if (context_egl->egl_context == NULL) - { - g_critical ("No EGL context associated to the GdkGLContext; you must " - "call gdk_gl_context_realize() first."); - return FALSE; - } - - surface = gdk_gl_context_get_surface (context); - - if (gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context))) - egl_surface = gdk_x11_surface_get_egl_surface (surface); - else - egl_surface = EGL_NO_SURFACE; - - GDK_DISPLAY_NOTE (display, OPENGL, - g_message ("Making EGL context %p current to surface %p", - context_egl->egl_context, egl_surface)); - - if (!eglMakeCurrent (display_x11->egl_display, egl_surface, egl_surface, context_egl->egl_context)) - { - GDK_DISPLAY_NOTE (display, OPENGL, - g_message ("Making EGL context current failed")); - return FALSE; - } - - if (gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context))) - { - gboolean do_frame_sync = FALSE; - - /* If the WM is compositing there is no particular need to delay - * the swap when drawing on the offscreen, rendering to the screen - * happens later anyway, and its up to the compositor to sync that - * to the vblank. */ - do_frame_sync = ! gdk_display_is_composited (display); - - if (do_frame_sync != context_x11->do_frame_sync) - { - context_x11->do_frame_sync = do_frame_sync; - - if (do_frame_sync) - eglSwapInterval (display_x11->egl_display, 1); - else - eglSwapInterval (display_x11->egl_display, 0); - } - } - - return TRUE; -} - /** * gdk_x11_display_get_egl_version: * @display: (type GdkX11Display): a `GdkDisplay` diff --git a/gdk/x11/gdkglcontext-glx.c b/gdk/x11/gdkglcontext-glx.c index 7d99d04a39..70489374c0 100644 --- a/gdk/x11/gdkglcontext-glx.c +++ b/gdk/x11/gdkglcontext-glx.c @@ -229,6 +229,66 @@ gdk_x11_gl_context_glx_end_frame (GdkDrawContext *draw_context, glXGetVideoSyncSGI (&info->last_frame_counter); } +static gboolean +gdk_x11_gl_context_glx_clear_current (GdkGLContext *context) +{ + GdkDisplay *display = gdk_gl_context_get_display (context); + Display *dpy = gdk_x11_display_get_xdisplay (display); + + glXMakeContextCurrent (dpy, None, None, NULL); + return TRUE; +} + +static gboolean +gdk_x11_gl_context_glx_make_current (GdkGLContext *context, + gboolean surfaceless) + +{ + GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context); + GdkX11GLContextGLX *context_glx = GDK_X11_GL_CONTEXT_GLX (context); + GdkDisplay *display = gdk_gl_context_get_display (context); + Display *dpy = gdk_x11_display_get_xdisplay (display); + gboolean do_frame_sync = FALSE; + GdkSurface *surface; + GLXWindow drawable; + + drawable = gdk_x11_gl_context_glx_get_drawable (context_glx); + + if (!surfaceless) + surface = gdk_gl_context_get_surface (context); + else + surface = GDK_X11_DISPLAY (display)->leader_gdk_surface; + drawable = gdk_x11_surface_get_glx_drawable (surface); + + GDK_DISPLAY_NOTE (display, OPENGL, + g_message ("Making GLX context %p current to drawable %lu", + context, (unsigned long) drawable)); + + if (!glXMakeContextCurrent (dpy, drawable, drawable, context_glx->glx_context)) + return FALSE; + + if (!surfaceless && GDK_X11_DISPLAY (display)->has_glx_swap_interval) + { + /* If the WM is compositing there is no particular need to delay + * the swap when drawing on the offscreen, rendering to the screen + * happens later anyway, and its up to the compositor to sync that + * to the vblank. */ + do_frame_sync = ! gdk_display_is_composited (display); + + if (do_frame_sync != context_x11->do_frame_sync) + { + context_x11->do_frame_sync = do_frame_sync; + + if (do_frame_sync) + glXSwapIntervalSGI (1); + else + glXSwapIntervalSGI (0); + } + } + + return TRUE; +} + static cairo_region_t * gdk_x11_gl_context_glx_get_damage (GdkGLContext *context) { @@ -675,6 +735,8 @@ gdk_x11_gl_context_glx_class_init (GdkX11GLContextGLXClass *klass) GObjectClass *gobject_class = G_OBJECT_CLASS (klass); context_class->realize = gdk_x11_gl_context_glx_realize; + context_class->make_current = gdk_x11_gl_context_glx_make_current; + context_class->clear_current = gdk_x11_gl_context_glx_clear_current; context_class->get_damage = gdk_x11_gl_context_glx_get_damage; draw_context_class->end_frame = gdk_x11_gl_context_glx_end_frame; @@ -841,67 +903,6 @@ gdk_x11_gl_context_glx_new (GdkSurface *surface, return GDK_X11_GL_CONTEXT (context); } -gboolean -gdk_x11_gl_context_glx_make_current (GdkDisplay *display, - GdkGLContext *context) -{ - GdkX11GLContextGLX *context_glx; - GdkX11GLContext *context_x11; - Display *dpy = gdk_x11_display_get_xdisplay (display); - gboolean do_frame_sync = FALSE; - GLXWindow drawable; - - if (context == NULL) - { - glXMakeContextCurrent (dpy, None, None, NULL); - return TRUE; - } - - context_glx = GDK_X11_GL_CONTEXT_GLX (context); - if (context_glx->glx_context == NULL) - { - g_critical ("No GLX context associated to the GdkGLContext; you must " - "call gdk_gl_context_realize() first."); - return FALSE; - } - - context_x11 = GDK_X11_GL_CONTEXT (context); - drawable = gdk_x11_gl_context_glx_get_drawable (context_glx); - - GDK_DISPLAY_NOTE (display, OPENGL, - g_message ("Making GLX context %p current to drawable %lu", - context, (unsigned long) drawable)); - - if (!glXMakeContextCurrent (dpy, drawable, drawable, context_glx->glx_context)) - { - GDK_DISPLAY_NOTE (display, OPENGL, - g_message ("Making GLX context current failed")); - return FALSE; - } - - if (gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context)) && - GDK_X11_DISPLAY (display)->has_glx_swap_interval) - { - /* If the WM is compositing there is no particular need to delay - * the swap when drawing on the offscreen, rendering to the screen - * happens later anyway, and its up to the compositor to sync that - * to the vblank. */ - do_frame_sync = ! gdk_display_is_composited (display); - - if (do_frame_sync != context_x11->do_frame_sync) - { - context_x11->do_frame_sync = do_frame_sync; - - if (do_frame_sync) - glXSwapIntervalSGI (1); - else - glXSwapIntervalSGI (0); - } - } - - return TRUE; -} - /** * gdk_x11_display_get_glx_version: * @display: (type GdkX11Display): a `GdkDisplay` diff --git a/gdk/x11/gdkglcontext-x11.c b/gdk/x11/gdkglcontext-x11.c index 4ecbf47a7d..88453663e8 100644 --- a/gdk/x11/gdkglcontext-x11.c +++ b/gdk/x11/gdkglcontext-x11.c @@ -82,22 +82,6 @@ gdk_x11_surface_create_gl_context (GdkSurface *surface, return GDK_GL_CONTEXT (context); } -gboolean -gdk_x11_display_make_gl_context_current (GdkDisplay *display, - GdkGLContext *context) -{ - GdkX11Display *display_x11 = GDK_X11_DISPLAY (display); - - if (display_x11->egl_display) - return gdk_x11_gl_context_egl_make_current (display, context); - else if (display_x11->glx_config) - return gdk_x11_gl_context_glx_make_current (display, context); - else - g_assert_not_reached (); - - return FALSE; -} - gboolean gdk_x11_display_init_gl_backend (GdkX11Display *self, Visual **out_visual, diff --git a/gdk/x11/gdkglcontext-x11.h b/gdk/x11/gdkglcontext-x11.h index 680fd91fb7..70cee907ab 100644 --- a/gdk/x11/gdkglcontext-x11.h +++ b/gdk/x11/gdkglcontext-x11.h @@ -65,8 +65,6 @@ gboolean gdk_x11_display_init_gl_backend (GdkX11Display * GdkGLContext * gdk_x11_surface_create_gl_context (GdkSurface *window, GError **error); -gboolean gdk_x11_display_make_gl_context_current (GdkDisplay *display, - GdkGLContext *context); /* GLX */ #define GDK_TYPE_X11_GL_CONTEXT_GLX (gdk_x11_gl_context_glx_get_type()) @@ -84,8 +82,6 @@ void gdk_x11_surface_destroy_glx_drawable (GdkX11Surface * GType gdk_x11_gl_context_glx_get_type (void) G_GNUC_CONST; GdkX11GLContext * gdk_x11_gl_context_glx_new (GdkSurface *surface, GError **error); -gboolean gdk_x11_gl_context_glx_make_current (GdkDisplay *display, - GdkGLContext *context); /* EGL */ @@ -105,8 +101,6 @@ void gdk_x11_surface_destroy_egl_surface (GdkX11Surface * GType gdk_x11_gl_context_egl_get_type (void) G_GNUC_CONST; GdkX11GLContext * gdk_x11_gl_context_egl_new (GdkSurface *surface, GError **error); -gboolean gdk_x11_gl_context_egl_make_current (GdkDisplay *display, - GdkGLContext *context); G_END_DECLS -- 2.30.2